package com.lvhx.service;

import com.github.rholder.retry.*;
import com.google.common.base.Predicates;

import java.io.IOException;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

public class PaymentService {
    // 模拟调用第三方支付API
    public boolean callPaymentApi(String orderId, double amount) throws IOException {
        System.out.println("尝试调用支付接口，订单ID: " + orderId + ", 金额: " + amount);

        // 模拟随机失败（实际应用中这里会是真实的API调用）
        double random = Math.random();
        if (random < 0.6) { // 60%概率失败
            throw new IOException("支付接口调用失败");
        }

        return true;
    }

    // 创建重试器
    private Retryer<Boolean> createRetryer() {
        return RetryerBuilder.<Boolean>newBuilder()
                // 当发生IOException时重试
                .retryIfExceptionOfType(IOException.class)
                // 当返回false时也重试
                .retryIfResult(Predicates.equalTo(false))
                // 重试策略：最多3次
                .withStopStrategy(StopStrategies.stopAfterAttempt(3))
                // 等待策略：每次间隔1秒
                .withWaitStrategy(WaitStrategies.fixedWait(1, TimeUnit.SECONDS))
                // 重试监听器（可选）
                .withRetryListener(new RetryListener() {
                    @Override
                    public <V> void onRetry(Attempt<V> attempt) {
                        System.out.println(String.format("第%d次重试，距离首次调用已过去%dms",
                                attempt.getAttemptNumber(),
                                attempt.getDelaySinceFirstAttempt()));

                        if (attempt.hasException()) {
                            System.out.println("失败原因: " + attempt.getExceptionCause().getMessage());
                        }
                    }
                })
                .build();
    }

    // 带重试机制的支付方法
    public boolean payWithRetry(String orderId, double amount) {
        Retryer<Boolean> retryer = createRetryer();

        Callable<Boolean> callable = () -> callPaymentApi(orderId, amount);

        try {
            return retryer.call(callable);
        } catch (RetryException e) {
            System.err.println("重试次数耗尽，最终失败: " + e.getMessage());
        } catch (ExecutionException e) {
            System.err.println("执行过程中发生异常: " + e.getCause().getMessage());
        }

        return false;
    }


}